/* 可持久化数据结构
    (1)trie的可持久化 01区分左右子树
    (2)线段树的可持久化——主席树

* 1.可持久化的前提:本身的拓扑结构不变

* 2.解决什么问题:可以存下来数据结构的所有历史版本

* 3.可持久化线段树难以进行区间修改操作

*/

// #define ONLINE_DUDGE
#pragma GCC optimize("O1,O2,O3,Ofast")
#pragma GCC optimize("no-stack-protector,unroll-loops,fast-math,inline")
#pragma GCC target("avx,avx2,fma")
#pragma GCC target("sse,sse2,sse3,sse4,sse4.1,sse4.2,ssse3")

#include <iostream>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
// #define int long long
const int N = 6e5+10, M = N*25; //每个数最多需要25位
int n, m;
int s[N]; //前缀序列和
int tree[M][2], max_id[M]; // 树(节点号) 记录当前节点版本的最大id范围，即当前点要存的数在前缀和数组s的位置
int root[N], idx; //每个版本节点(根节点) 节点总和

void insert(int i, int k, int p, int q)
{//插入的第i个数 还需记录k个数 上一个插入的数的节点号 当前插入的数的节点号
    if(k < 0){ //记录结束
        max_id[q] = i; //当前节点能达到的最大范围
        return;
    }
    // 取出前缀和的二进制表示从右向左第k位v
    int v = s[i] >> k & 1;

    //前一个节点p存在当前节点q没有的分支(不同于v方向)，则进行连接(复制)
    if(p) tree[q][v^1] = tree[p][v^1];

    tree[q][v] = ++idx; //trie插入
    //递归连接
    insert(i, k-1, tree[p][v], tree[q][v]);
    
    //之前连接不同于v方向的边，在下一轮中插入v方向的边: q新插入的数字是v，而q在这条路径上也是v，s[i]的第k位v没有修改，仍可使用，暂时不需要复制
    //e.g. (版本号)1.v是0 2.v是1,发生复制,且2.v连接原始节点 3.v是1(保存1.v=0) 4.v是1(保存1.v=0) 5.v是0,此时只需要保存4.v是1的路径,5.v=0与1.v=0路径重合

    //每个点的最大范围用子节点最大的值, 然后还能递归传递回去, 因为当前递归层的q, 就是上一层的tr[q][v], 观察易知每个节点都会有对应max_id
    max_id[q] = max(max_id[tree[q][0]], max_id[tree[q][1]]);
}

int query(int root, int C, int L)
{
    int p = root;
    for(int i = 23; i >= 0; i--)
    {
        int v = C >> i & 1;
        if(max_id[tree[p][v^1]] >= L) p = tree[p][v^1]; //对立节点存在
        else p = tree[p][v]; //否则只能顺着向下走
    }
    return C ^ s[max_id[p]];
}
signed main()
{

    #ifdef ONLINE_JUDGE
    ios::sync_with_stdio(false);   
	cin.tie(0);
    #else
    freopen("./in.txt","r",stdin);
    #endif

    cin >> n >> m;
    //root[0]
    max_id[0] = -1;
    root[0] = ++idx;
    insert(0, 23, 0, root[0]);
    for(int i = 1; i <= n; i++){
       int x; cin >> x; 
       s[i] = s[i-1]^x;
       root[i] = ++idx; //新版本
       insert(i, 23, root[i-1], root[i]);
    } 

    while(m--)
    {
        char op; cin >> op;
        if(op == 'A'){ //插入
            int x; cin >> x;
            n++;
            s[n] = s[n-1]^x;
            root[n] = ++idx;
            insert(n, 23, root[n-1], root[n]);
        }
        else{ //查询
            int l, r, x; cin >> l >> r >> x;
            cout << query(root[r-1], x^s[n], l-1) << endl;
        }
    }


    
    return 0;
}
